package com.me.seckill.filter;

import java.io.IOException;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;

/**
 * @Title:
 * @author ME
 * @date 2017年10月25日 下午3:53:41
 * 
 * @Description: 防御XSS攻击的过滤器
 */
@Slf4j
// @Component
@Order(Integer.MAX_VALUE)
public class MyFilter implements Filter {

	/**
	 * 配置文件中配置需要排除的URL
	 */
	private String excludedUrl;

	/**
	 * 正则表达式的编译后的匹配模版
	 */
	private Pattern[] pattenArray;

	/**
	 * 对于一部分参数，值本身就包含特殊字符
	 */
	private String[] excludeParameter;

	/**
	 * 初始化函数，获取需要排除在外的url
	 */
	@Override
	public void init(FilterConfig filterConfig) {
		excludedUrl = filterConfig.getInitParameter("excludedUrl");
		if (StringUtils.isNotEmpty(excludedUrl)) {
			String[] excludedUrlArray = excludedUrl.split(",");
			pattenArray = new Pattern[excludedUrlArray.length];

			for (int i = 0; i < excludedUrlArray.length; i++) {
				pattenArray[i] = Pattern.compile(excludedUrlArray[i]);
			}
			excludedUrlArray = null;
		} else {
			pattenArray = new Pattern[0];
		}
		String excludeParameterStr = filterConfig.getInitParameter("excludeParameter");
		if (StringUtils.isNotEmpty(excludeParameterStr)) {
			excludeParameter = excludeParameterStr.split(",");
			for (int i = 0; i < excludeParameter.length; i++) {
				excludeParameter[i] = excludeParameter[i].trim();
			}
		} else {
			excludeParameter = new String[0];
		}
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
			ServletException {
		log.info("<== MyFilter.");
		HttpServletRequest httpReq = (HttpServletRequest) request;
		if (HttpMethod.OPTIONS.name().equals(httpReq.getMethod())) {
			chain.doFilter(request, response);
		}
		boolean isExcludedUrl = false;
		for (Pattern patten : pattenArray) {
			if (patten.matcher(httpReq.getRequestURI()).find()) {
				isExcludedUrl = true;
				break;
			}
		}

		if (isExcludedUrl) {
			chain.doFilter(request, response);
		} else {
			// TODO 特殊处理
			chain.doFilter(httpReq, response);
		}
		log.info("==> MyFilter.");
	}

	@Override
	public void destroy() {
	}

}
